import requests
import logging
import threading
import allure
from utils.slow_api_write_csv import ApiLogger


class HttpRequester:

    def __init__(self,timeout=3):
        self.__timeout = timeout
        self.__api_logger = ApiLogger()

    def __log_slow_api_async(self,res,request_data,response):
        """
        异步写入慢接口的函数
        :param res: 返回结果的最原始内容（未做处理版）
        :param request_data: 请求的参数
        :param response: 组装过的返回结果
        :return:
        """
        def log():
            self.__api_logger.log_request(res.url, request_data.get("method"), request_data.get("params"), request_data.get("data"),
                                          request_data.get("json"), response.get("response_time"))
        threading.Thread(target=log()).start()

    @allure.step("2.发送Http请求")
    def send_request(self,**request_data):
        """
        提供给外部调用的发起请求的方法，本质发起请求是通过私有方法来实现的
        :param request_data: 请求需要的字典数据
        :return: 请求之后的response
        """
        return self.__send_requests(**request_data)

    def __send_requests(self,**request_data):

        # 必填项参数
        requited_field = ["method","url"]
        if not all(field in request_data for field in requited_field):
            raise ValueError(f"http请求缺少必传参数：{requited_field}")

        # 把默认超时时间加入到请求的参数字典里
        request_data.setdefault("timeout",self.__timeout)
        try:
            res = requests.request(**request_data)

        except requests.RequestException as e:
            logging.error(f"Http请求失败，异常是{e}")
            logging.error(f"Http请求失败，参数是{request_data}")
            return {"error":str(e)}

        except Exception as e:
            logging.error(f"HTTP请求发送未知错误,{e}")
            return {"error": str(e)}
        else:
            # 判断返回值是否是json，是json就转字典，不是就转文本
            try:
                data = res.json()

            except ValueError:
                data = res.text

        response = {
            "status_code": res.status_code,
            "json_data": data,
            # "JSESSIONID":res.cookies.get("JSESSIONID"),
            "response_time": res.elapsed.total_seconds() * 1000
        }
        logging.info(f"2.发送HTTP请求，响应文本为：{response}")

        # 写入慢接口
        self.__api_logger.log_request(res.url, request_data["method"], request_data["params"], request_data["data"],
                                request_data["json"], response["response_time"])

        # 调用异步写入慢接口
        self.__log_slow_api_async(res,request_data,response)
        return response
